package ebedynky.services;

import ebedynky.beans.HibernateUtil;
import ebedynky.beans.Message;
import ebedynky.beans.Supplier;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;

/**
 * @author davidon1
 */
public class SupplierService {

    /**
     * Seesion - current connection to the db.
     */
    private Session session;

    /**
     * Constructor, retrieces the session (connection).
     */
    public SupplierService() {
        this.session = HibernateUtil.getSessionFactory().openSession();
    }

    /**
     * Closes the session (connection).
     * @return success/failure.
     */
    public boolean close() {
        this.session.close();
        return !(this.session.isOpen());
    }

    /**
     * Restarts the session (connection).
     * @return success/failure.
     */
    public boolean restart() {
        this.session.close();
        if (this.session.isOpen()) {
            throw new IllegalStateException("Session could not be closed.");
        }
        this.session = HibernateUtil.getSessionFactory().openSession();
        return this.session.isOpen();
    }

    /**
     * Adds supplier to the db.
     * @param sup Supplier to be inserted
     * @return ID of the added supplier
     */
    public int addSupplier(Supplier sup) {
        session.beginTransaction();
        int id = getMaxSupplierID() + 1;
        sup.setSupplierID(id);
        id = (Integer) session.save(sup);
        session.getTransaction().commit();
        return (id);
    }

    /**
     * Retrieves the maximum id currently in the database of suppliers.
     * @return Max ID
     */
    public int getMaxSupplierID() {
        String hql = "select max(u.userID) from User u";
        List list = session.createQuery(hql).list();
        if (list.get(0) != null) {
            Integer maxsupid = (Integer) list.get(0);
            return maxsupid;
        } else {
            return 0;
        }
    }

    /**
     * Retrieves a supplier identified by the ID.
     * @param id of the Supplier
     * @return Supplier with the ID given (null if not found)
     */
    public Supplier getSupplierByID(int id) {
        session.beginTransaction();
        Supplier sup = (Supplier) session.get(Supplier.class, new Integer(id));
        session.getTransaction().commit();
        return (sup);
    }

    /**
     * Retrieves a list of all suppliers stored in the db.
     * @return List of all Suppliers (null if no suppliers)
     */
    public List<Supplier> getAllSuppliers() {
        session.beginTransaction();
        List<Supplier> supList = session.createQuery("from Supplier").list();
        session.getTransaction().commit();
        return (supList);
    }

    /**
     * Updates a specified supplier identified by ID.
     * @param newSupplier an updated supplier
     */
    public void updateSupplier(Supplier newSupplier) {
        session.beginTransaction();
        Supplier sup = (Supplier) session.get(Supplier.class, new Integer(newSupplier.getUserID()));
        sup.setAccountState(newSupplier.getAccountState());
        sup.setRoles(newSupplier.getRoles());
        sup.setStreet(newSupplier.getStreet());
        sup.setStreetNo(newSupplier.getStreetNo());
        sup.setCity(newSupplier.getCity());
        sup.setZip(newSupplier.getZip());
        sup.setEmail(newSupplier.getEmail());
        sup.setFroms(newSupplier.getFroms());
        sup.setName(newSupplier.getName());
        sup.setPass(newSupplier.getPass());
        sup.setSurname(newSupplier.getSurname());
        sup.setTos(newSupplier.getTos());
        sup.setUsername(newSupplier.getUsername());
        sup.setGranges(newSupplier.getGranges());
        sup.setNotes(newSupplier.getNotes());
        sup.setOffers(newSupplier.getOffers());
        sup.setOffers_1(newSupplier.getOffers_1());
        session.flush();
        session.getTransaction().commit();
        session.clear();
    }

    /**
     * Removes the Supplier from db.
     * @param id Supplier ID for removal
     * @return true if successful, false otherwise
     */
    public boolean deleteSupplier(int id) {
        try {
            session.beginTransaction();
            Supplier sup = (Supplier) session.get(Supplier.class, new Integer(id));
            session.delete(sup);
            session.getTransaction().commit();
            return (true);
        } catch (HibernateException ex) {
            return (false);
        }
    }

    /**
     * Returns all messages that were aimed to this supplier.
     * @param supplier for whom the messages are to be found
     * @return list of messages
     */
    public List<Message> getToMessages(Supplier sup) {
        if (sup == null || sup.getTos() == null || sup.getTos().isEmpty())
            return new ArrayList<Message>(0);
        return new ArrayList<Message>(sup.getTos());
    }

    /**
     * Returns all messages that were aimed to this supplier.
     * @param id for whom the messages are to be found
     * @return list of messages
     */
    public List<Message> getToMessages(int id) {
        return getToMessages(getSupplierByID(id));
    }

    /**
     * Returns all messages that were aimed from this supplier.
     * @param supplier for whom the messages are to be found
     * @return list of messages
     */
    public List<Message> getFromMessages(Supplier sup) {
        if (sup == null || sup.getTos() == null || sup.getTos().isEmpty())
            return new ArrayList<Message>(0);
        return new ArrayList<Message>(sup.getFroms());
    }

    /**
     * Returns all messages that were aimed from this supplier.
     * @param id for whom the messages are to be found
     * @return list of messages
     */
    public List<Message> getFromMessages(int id) {
        return getFromMessages(getSupplierByID(id));
    }

    /**
     * Returns all messages that were aimed to/from this supplier.
     * @param supplier for whom the messages are to be found
     * @return list of messages
     */
    public List<Message> getAllMessages(Supplier sup) {
        if (sup == null || sup.getTos() == null || sup.getTos().isEmpty())
            return new ArrayList<Message>(0);
        ArrayList<Message> am = new ArrayList<Message>(sup.getTos());
        if (sup.getFroms() != null && !sup.getFroms().isEmpty())
            am.addAll(sup.getFroms());
        return am;
    }

    /**
     * Returns all messages that were aimed to/from this supplier.
     * @param id for whom the messages are to be found
     * @return list of messages
     */
    public List<Message> getAllMessages(int id) {
        return getAllMessages(getSupplierByID(id));
    }

    /**
     * Returns all unread messages that were aimed to this supplier.
     * @param supplier for whom the messages are to be found
     * @return list of messages
     */
    public List<Message> getAllUnreadMessages(Supplier sup) {
        if (sup == null || sup.getTos() == null || sup.getTos().isEmpty())
            return new ArrayList<Message>(0);
        ArrayList<Message> am = new ArrayList<Message>(sup.getTos());
        for (Message m : am)
            if (!m.isUnread())
                am.remove(m);
        return am;
    }

    /**
     * Returns all unread messages that were aimed to this supplier.
     * @param id for whom the messages are to be found
     * @return list of messages
     */
    public List<Message> getAllUnreadMessages(int id) {
        return getAllUnreadMessages(getSupplierByID(id));
    }
}
